import { isArray, isFunction, isObject, isString } from "./index";

export const format = {
	/**
	 * 将输入转换为数字或数字数组。
	 * @param {*} value 输入值
	 * @returns {(number|Array<number|undefined>)} 转换后的数字或数组，无法转换时为 undefined
	 */
	number(value) {
        let result;
        if (isArray(value)) {
            result = value.map(Number).map(item => isNaN(item) ? undefined : item);
        } else {
            result = Number(value);
            if (isNaN(result)) {
                result = undefined;
            }
        }
        return result;
	},

	/**
	 * 将输入转换为字符串或字符串数组。
	 * @param {*} value 输入值
	 * @returns {(string|Array<string>)} 转换后的字符串或数组
	 */
	string(value) {
		return isArray(value) ? value.map(String) : String(value);
	},

	/**
	 * 以逗号分割字符串。
	 * @param {string} value 输入字符串
	 * @returns {Array<string>} 分割后的字符串数组
	 */
	split(value) {
		return isString(value) ? value.split(",").filter(Boolean) : value;
	},

	/**
	 * 使用逗号连接数组。
	 * @param {Array<string>} value 字符串数组
	 * @returns {string} 连接后的字符串
	 */
	join(value) {
		return isArray(value) ? value.join(",") : value;
	},

	/**
	 * 将输入转换为布尔值。
	 * @param {*} value 输入值
	 * @returns {boolean} 转换后的布尔值
	 */
	boolean(value) {
		return Boolean(value);
	},

	/**
	 * 根据布尔值返回 1 或 0。
	 * @param {*} value 输入值
	 * @returns {number} 布尔值为真时返回 1，否则返回 0
	 */
	booleanNumber(value) {
		return Boolean(value) ? 1 : 0;
	},

	/**
	 * 处理日期范围的转换。
	 * @param {Array<Date>} value 输入日期范围数组 [开始时间, 结束时间]
	 * @param {Object} form 表单对象
	 * @param {string} method 方法名称 ("bind" 或 "submit")
	 * @returns {(Array<Date>|undefined)} 根据方法返回数组或 undefined
	 */
	datetimerange(value, form, method) {
		if (method === "bind") {
			return [form.startTime, form.endTime];
		} else {
			const [startTime, endTime] = value || [];
			form.startTime = startTime;
			form.endTime = endTime;
			return undefined;
		}
	},

	/**
	 * 根据方法将逗号分割字符串与数组连接转换。
	 * @param {*} value 输入值
	 * @param {*} _ 预留参数（未使用）
	 * @param {string} method 方法名称 ("bind" 或其他)
	 * @returns {(Array<string>|string)} 转换后的结果
	 */
	splitJoin(value, _, method) {
		if (method === "bind") {
			return isString(value) ? value.split(",").filter(Boolean) : value;
		} else {
			return isArray(value) ? value.join(",") : value;
		}
	}
};

/**
 * 解析管道处理函数
 * @param {string} method 方法名称 ("bind" 或 "submit")
	 * @param {Object} options 选项对象
	 * @param {*} options.value 输入值
	 * @param {(string|Array<string>|Object|Function)} options.pipe 管道处理，类型可为字符串、数组、对象或函数
	 * @param {Object} options.form 表单对象
	 * @returns {*} 处理后的值
	 */
function parse(method, { value, pipe, form }) {
	if (!pipe) {
		return value;
	}

	let pipes = [];

	if (isString(pipe)) {
		if (format[pipe]) {
			pipes = [pipe];
		} else {
			console.error(`${pipe} is not found.`);
			return value;
		}
	} else if (isArray(pipe)) {
		pipes = pipe;
	} else if (isObject(pipe)) {
		pipes = isArray(pipe[method]) ? pipe[method] : [pipe[method]];
	} else if (isFunction(pipe)) {
		pipes = [pipe];
	} else {
		console.error(`Hook data error!`);
		return value;
	}

	let d = value;
	pipes.forEach((e) => {
		if (isString(e)) {
			d = format[e](d, form, method);
		} else if (isFunction(e)) {
			d = e(d, form);
		}
	});

	return d;
}

export default {
	/**
	 * 绑定数据处理入口
	 * @param {*} value 输入值
	 * @param {(string|Array<string>|Object|Function)} pipe 管道处理规则
	 * @param {Object} form 表单数据对象
	 * @returns {*} 处理后的值
	 */
	bind(value, pipe, form) {
		return parse("bind", { value, pipe, form });
	},

	/**
	 * 提交数据处理入口
	 * @param {*} value 输入值
	 * @param {(string|Array<string>|Object|Function)} pipe 管道处理规则
	 * @param {Object} form 表单数据对象
	 * @returns {*} 处理后的值
	 */
	submit(value, pipe, form) {
		return parse("submit", { value, pipe, form });
	}
};